package com.zqxx.examine.management.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.extr.file.util.ExcelUtil;
import com.google.gson.Gson;
import com.zqxx.examine.common.utils.Page;
import com.zqxx.examine.management.persistence.QuestionMapper;
import com.zqxx.examine.model.question.Field;
import com.zqxx.examine.model.question.KnowledgePoint;
import com.zqxx.examine.model.question.PointStatistic;
import com.zqxx.examine.model.question.Question;
import com.zqxx.examine.model.question.QuestionContent;
import com.zqxx.examine.model.question.QuestionFilter;
import com.zqxx.examine.model.question.QuestionQueryResult;
import com.zqxx.examine.model.question.QuestionStatistic;
import com.zqxx.examine.model.question.QuestionStruts;
import com.zqxx.examine.model.question.QuestionTag;
import com.zqxx.examine.model.question.QuestionType;
import com.zqxx.examine.model.question.Tag;

@Service
public class QuestionService {

	  @Autowired
	  private QuestionMapper questionMapper;
	  
	  public List<Question> getQuestionList(Page<Question> pageModel, QuestionFilter qf)
	  {
		  //TODO 重写
		  
	    return this.questionMapper.getQuestionList(qf, pageModel);
	  }
	  
	  public List<Field> getAllField(Page<Field> page)
	  {
	    return this.questionMapper.getAllField(page);
	  }
	  
	  public List<KnowledgePoint> getKnowledgePointByFieldId(int fieldId, Page<KnowledgePoint> page)
	  {
	    return this.questionMapper.getKnowledgePointByFieldId(fieldId, page);
	  }
	  
	  public List<QuestionType> getQuestionTypeList()
	  {
	    return this.questionMapper.getQuestionTypeList();
	  }
	  
	  public List<Tag> getTags(Page<Tag> page)
	  {
	    return this.questionMapper.getTags(page);
	  }
	  
	  public void addTag(Tag tag)
	  {
	    this.questionMapper.addTag(tag);
	  }
	  
	  @Transactional
	  public void addQuestion(Question question)
	  {
	    try
	    {
	      this.questionMapper.insertQuestion(question);
	      for (Integer i : question.getPointList()) {
	        this.questionMapper.addQuestionKnowledgePoint(question.getId(), i.intValue());
	      }
	    }
	    catch (Exception e)
	    {
	      throw new RuntimeException(e.getMessage());
	    }
	  }
	  
	  public void addField(Field field)
	  {
	    this.questionMapper.addField(field);
	  }
	  
	  public void addKnowledgePoint(KnowledgePoint point)
	  {
	    this.questionMapper.addKnowledgePoint(point);
	  }
	  
	  public List<QuestionTag> getQuestionTagByQuestionIdAndUserId(int questionId, int userId, Page<QuestionTag> page)
	  {
	    return this.questionMapper.getQuestionTagByQuestionIdAndUserId(questionId, userId, page);
	  }
	  
	  @Transactional
	  public void addQuestionTag(int questionId, int userId, List<QuestionTag> questionTagList)
	  {
	    try
	    {
	      List<Integer> idList = new ArrayList();
	      for (QuestionTag t : questionTagList) {
	        idList.add(Integer.valueOf(t.getTagId()));
	      }
	      this.questionMapper.deleteQuestionTag(questionId, userId, idList.size() == 0 ? null : idList);
	      this.questionMapper.addQuestionTag(questionTagList);
	    }
	    catch (Exception e)
	    {
	      throw new RuntimeException(e);
	    }
	  }
	  
	  @Transactional
	  public void updateQuestionPoint(Question question, int userId, List<QuestionTag> questionTagList)
	  {
	    try
	    {
	      this.questionMapper.deleteQuestionPointByQuestionId(question.getId());
	      for (Iterator localIterator = question.getPointList().iterator(); localIterator.hasNext();)
	      {
	    	  Integer id = ((Integer)localIterator.next()).intValue();
	        this.questionMapper.addQuestionKnowledgePoint(question.getId(), id);
	      }
	      int id;
	      Object idList = new ArrayList();
	      for (QuestionTag t : questionTagList) {
	        ((List)idList).add(Integer.valueOf(t.getTagId()));
	      }
	      if ((questionTagList != null) && (questionTagList.size() != 0))
	      {
	        this.questionMapper.deleteQuestionTag(question.getId(), userId, ((List)idList).size() == 0 ? null : (List)idList);
	        this.questionMapper.addQuestionTag(questionTagList);
	      }
	      else
	      {
	        this.questionMapper.deleteQuestionTag(question.getId(), userId, ((List)idList).size() == 0 ? null : (List)idList);
	      }
	    }
	    catch (Exception e)
	    {
	      e.printStackTrace();
	      throw new RuntimeException(e.getClass().getName());
	    }
	  }
	  
	  public void deleteFieldByIdList(List<Integer> idList)
	  {
	    this.questionMapper.deleteFieldByIdList(idList);
	  }
	  
	  public void deleteKnowledgePointByIdList(List<Integer> idList)
	  {
	    this.questionMapper.deleteKnowledgePointByIdList(idList);
	  }
	  
	  public void deleteTagByIdList(List<Integer> idList)
	  {
	    this.questionMapper.deleteTagByIdList(idList);
	  }
	  
	  public Question getQuestionByQuestionId(int questionId)
	  {
	    return this.questionMapper.getQuestionByQuestionId(questionId);
	  }
	  
	  public List<QuestionQueryResult> getQuestionDescribeListByIdList(List<Integer> idList)
	  {
		  
	    List<QuestionQueryResult> questionList = this.questionMapper.getQuestionAnalysisListByIdList(idList);
	    //TODO 补充未添加的项
	    return questionList;
	  }
	  
	  public void deleteQuestionByQuestionId(int questionId)
	  {
	    this.questionMapper.deleteQuestionByQuestionId(questionId);
	  }
	  
	  public HashMap<Integer, HashMap<Integer, List<QuestionStruts>>> getQuestionStrutsMap(List<Integer> idList)
	  {
	    HashMap<Integer, HashMap<Integer, List<QuestionStruts>>> hm = new HashMap();
	    List<QuestionStruts> questionList = this.questionMapper.getQuestionListByPointId(idList);
	    for (QuestionStruts q : questionList)
	    {
	      HashMap<Integer, List<QuestionStruts>> hashmap = new HashMap();
	      List<QuestionStruts> ql = new ArrayList();
	      if (hm.containsKey(Integer.valueOf(q.getPointId()))) {
	        hashmap = (HashMap)hm.get(Integer.valueOf(q.getPointId()));
	      }
	      if (hashmap.containsKey(Integer.valueOf(q.getQuestionTypeId()))) {
	        ql = (List)hashmap.get(Integer.valueOf(q.getQuestionTypeId()));
	      }
	      ql.add(q);
	      hashmap.put(Integer.valueOf(q.getQuestionTypeId()), ql);
	      hm.put(Integer.valueOf(q.getPointId()), hashmap);
	    }
	    return hm;
	  }
	  
	  @Transactional
	  public void uploadQuestions(String filePath, String username, int fieldId)
	  {
	    String strPath = ",webapps,files,question," + username + ",tmp";
	    
	    filePath = System.getProperty("catalina.base") + strPath.replace(',', File.separatorChar) + File.separatorChar + filePath;
	    
	    Map<String, KnowledgePoint> pointMap = getKnowledgePointMapByFieldId(fieldId, null);
	    int index = 2;
	    try
	    {
	      List<Map<String, String>> questionMapList = ExcelUtil.ExcelToList(filePath);
	      for (Map<String, String> map : questionMapList)
	      {
	        System.out.println(map);
	        Question question = new Question();
	        question.setName(((String)map.get("题目")).length() > 10 ? ((String)map.get("题目")).substring(0, 10) + "..." : (String)map.get("题目"));
	        if ((((String)map.get("类型")).equals("单选题")) || (((String)map.get("类型")).equals("单项选择题"))) {
	          question.setQuestion_type_id(1);
	        } else if ((((String)map.get("类型")).equals("多选题")) || (((String)map.get("类型")).equals("多项选择题"))) {
	          question.setQuestion_type_id(2);
	        } else if (((String)map.get("类型")).equals("判断题")) {
	          question.setQuestion_type_id(3);
	        } else if (((String)map.get("类型")).equals("填空题")) {
	          question.setQuestion_type_id(4);
	        } else if (((String)map.get("类型")).equals("简答题")) {
	          question.setQuestion_type_id(5);
	        } else if (((String)map.get("类型")).equals("论述题")) {
	          question.setQuestion_type_id(6);
	        } else if (((String)map.get("类型")).equals("分析题")) {
	          question.setQuestion_type_id(7);
	        }
	        question.setAnalysis((String)map.get("解析"));
	        question.setAnswer((String)map.get("答案"));
	        if (question.getQuestion_type_id() == 3)
	        {
	          if (((String)map.get("答案")).equals("对")) {
	            question.setAnswer("T");
	          }
	          if (((String)map.get("答案")).equals("错")) {
	            question.setAnswer("F");
	          }
	        }
	        KnowledgePoint kp = (KnowledgePoint)pointMap.get(map.get("知识类"));
	        if (kp == null) {
	          throw new Exception("知识类不存在：" + (String)map.get("知识类"));
	        }
	        List<Integer> pointList = new ArrayList();
	        pointList.add(Integer.valueOf(kp.getPointId()));
	        question.setReferenceName((String)map.get("出处"));
	        question.setExamingPoint((String)map.get("知识点"));
	        question.setKeyword((String)map.get("知识关键点"));
	        question.setPoints(((String)map.get("分值")).equals("") ? 0.0F : Float.parseFloat((String)map.get("分值")));
	        QuestionContent qc = new QuestionContent();
	        
	        Iterator<String> it = map.keySet().iterator();
	        List<String> keyStr = new ArrayList();
	        while (it.hasNext())
	        {
	          String key = (String)it.next();
	          if (key.contains("选项")) {
	            keyStr.add(key.replace("选项", ""));
	          }
	        }
	        Collections.sort(keyStr);
	        LinkedHashMap<String, String> choiceList = new LinkedHashMap();
	        for (int i = 0; i < keyStr.size(); i++) {
	          if (!((String)map.get("选项" + (String)keyStr.get(i))).trim().equals("")) {
	            choiceList.put(keyStr.get(i), map.get("选项" + (String)keyStr.get(i)));
	          }
	        }
	        if ((question.getQuestion_type_id() == 1) || (question.getQuestion_type_id() == 2)) {
	          qc.setChoiceList(choiceList);
	        }
	        qc.setTitle((String)map.get("题目"));
	        Gson gson = new Gson();
	        String content = gson.toJson(qc);
	        question.setContent(content);
	        question.setCreator(username);
	        question.setPointList(pointList);
	        addQuestion(question);
	        index++;
	      }
	    }
	    catch (Exception e)
	    {
	      e.printStackTrace();
	      throw new RuntimeException("第" + index + "行有错误，请检查！" + e.getMessage());
	    }
	  }
	  
	  public Map<String, KnowledgePoint> getKnowledgePointMapByFieldId(int fieldId, Page<KnowledgePoint> page)
	  {
	    Map<String, KnowledgePoint> map = new HashMap();
	    List<KnowledgePoint> pointList = this.questionMapper.getKnowledgePointByFieldId(fieldId, page);
	    for (KnowledgePoint point : pointList) {
	      map.put(point.getPointName(), point);
	    }
	    return map;
	  }
	  
	  public Map<Integer, Map<Integer, QuestionStatistic>> getTypeQuestionStaticByFieldId(int fieldId)
	  {
	    List<QuestionStatistic> statisticList = this.questionMapper.getTypeQuestionStaticByFieldId(fieldId);
	    Map<Integer, Map<Integer, QuestionStatistic>> map = new HashMap();
	    for (QuestionStatistic statistic : statisticList)
	    {
	      Map<Integer, QuestionStatistic> tmp = (Map)map.get(Integer.valueOf(statistic.getPointId()));
	      if (tmp == null) {
	        tmp = new HashMap();
	      }
	      tmp.put(Integer.valueOf(statistic.getQuestionTypeId()), statistic);
	      map.put(Integer.valueOf(statistic.getPointId()), tmp);
	    }
	    return map;
	  }
	  
	  public Map<Integer, String> getKnowledgePointMap(int fieldId)
	  {
	    List<KnowledgePoint> knowledgeList = null;
	    if (fieldId == 0) {
	      knowledgeList = this.questionMapper.getKnowledgePointByFieldId(0, null);
	    } else {
	      knowledgeList = this.questionMapper.getKnowledgePointByFieldId(fieldId, null);
	    }
	    Map<Integer, String> knowledgeMap = new HashMap();
	    for (KnowledgePoint kp : knowledgeList) {
	      knowledgeMap.put(Integer.valueOf(kp.getPointId()), kp.getPointName());
	    }
	    return knowledgeMap;
	  }
	  
	  public Map<Integer, String> getQuestionTypeMap()
	  {
	    List<QuestionType> typeList = getQuestionTypeList();
	    Map<Integer, String> typeMap = new HashMap();
	    for (QuestionType tp : typeList) {
	      typeMap.put(Integer.valueOf(tp.getId()), tp.getName());
	    }
	    return typeMap;
	  }
	  
	  @Transactional
	  public void updateQuestion(Question question, List<QuestionTag> questionTagList)
	  {
	    try
	    {
	      this.questionMapper.updateQuestion(question);
	      this.questionMapper.deleteQuestionPointByQuestionId(question.getId());
	      for (Iterator localIterator = question.getPointList().iterator(); localIterator.hasNext();)
	      {
	    	  Integer id = ((Integer)localIterator.next()).intValue();
	        this.questionMapper.addQuestionKnowledgePoint(question.getId(), id);
	      }
	      int id;
	      Object idList = new ArrayList();
	      for (QuestionTag t : questionTagList) {
	        ((List)idList).add(Integer.valueOf(t.getTagId()));
	      }
	      if ((questionTagList != null) && (questionTagList.size() != 0))
	      {
	        this.questionMapper.deleteQuestionTag(question.getId(), 0, null);
	        this.questionMapper.addQuestionTag(questionTagList);
	      }
	      else
	      {
	        this.questionMapper.deleteQuestionTag(question.getId(), 0, null);
	      }
	    }
	    catch (Exception e)
	    {
	      throw new RuntimeException(e.getClass().getName());
	    }
	  }
	  
	  @Transactional
	  public Question getQuestionDetail(int questionId, int userId)
	  {
	    try
	    {
	      Question question = this.questionMapper.getQuestionByQuestionId(questionId);
	      List<QuestionTag> tagList = this.questionMapper.getQuestionTagByQuestionIdAndUserId(questionId, userId, null);
	      List<KnowledgePoint> pointList = this.questionMapper.getQuestionPoint(questionId);
	      question.setTagList(tagList);
	      question.setKnowledgePoint(pointList);
	      return question;
	    }
	    catch (Exception e)
	    {
	      e.printStackTrace();
	      throw new RuntimeException(e);
	    }
	  }
	  
	  public List<PointStatistic> getPointCount(int fieldId, Page<PointStatistic> page)
	  {
	    return this.questionMapper.getPointCount(fieldId, page);
	  }
}
